package com.kexio.user.entity;

import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.kexio.common.entity.BaseEntity;

/**
 * 用户实体类
 * 
 * 对应数据库表 sys_user
 * 存储系统用户的基本信息、状态和权限相关信息
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@TableName("sys_user")
public class User extends BaseEntity {
    
    /**
     * 用户ID（主键）- UUID字符串
     */
    @TableId(value = "id", type = IdType.ASSIGN_UUID)
    private String id;
    
    /**
     * 租户ID
     */
    @TableField("tenant_id")
    private String tenantId;
    
    
    /**
     * 用户名
     */
    @TableField("username")
    private String username;
    
    /**
     * 密码（BCrypt加密）
     */
    @TableField("password")
    @JsonIgnore
    private String password;
    
    /**
     * 昵称
     */
    @TableField("nickname")
    private String nickname;
    
    /**
     * 部门ID
     */
    @TableField("dept_id")
    private String deptId;
    
    /**
     * 手机号
     */
    @TableField("phone")
    private String phone;
    
    /**
     * 邮箱
     */
    @TableField("email")
    private String email;
    
    /**
     * 邮箱是否已验证
     */
    @TableField("email_verified")
    private Boolean emailVerified;
    
    /**
     * 邮箱验证完成时间
     */
    @TableField("email_verified_at")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime emailVerifiedAt;
    
    /**
     * 头像URL
     */
    @TableField("avatar_url")
    private String avatarUrl;
    
    /**
     * 状态：1-启用，0-禁用
     */
    @TableField("status")
    private Integer status;
    
    /**
     * 是否锁定
     */
    @TableField("is_locked")
    private Boolean isLocked;
    
    /**
     * 密码过期时间
     */
    @TableField("password_expire_at")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime passwordExpireAt;
    
    /**
     * 最后登录时间
     */
    @TableField("last_login_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime lastLoginTime;
    
    /**
     * 最后登录IP地址
     */
    @TableField("last_login_ip")
    private String lastLoginIp;
    
    /**
     * 最后密码修改时间
     */
    @TableField("last_password_change_at")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime lastPasswordChangeAt;
    
    /**
     * 密码错误次数
     */
    @TableField("password_error_count")
    private Integer passwordErrorCount;
    
    /**
     * 锁定时间
     */
    @TableField("lock_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime lockTime;
    
    /**
     * 解锁时间
     */
    @TableField("unlock_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime unlockTime;
    
    /**
     * 权限版本号（用于缓存一致性）
     */
    @TableField("perm_version")
    private Long permVersion;
    
    /**
     * 用户描述/备注
     */
    @TableField("description")
    private String description;
    
    /**
     * 用户角色列表（非数据库字段，用于JOIN查询结果映射）
     */
    @TableField(exist = false)
    private java.util.List<Role> roles;
    
    /**
     * 删除标记
     * 
     * 重写父类字段以启用逻辑删除。
     * 0表示未删除，1表示已删除。
     */
    @TableField(value = "deleted", fill = FieldFill.INSERT)
    @TableLogic(value = "0", delval = "1")
    @JsonIgnore
    private Integer deleted;
    




    
    // ==================== 便捷方法 ====================
    
    /**
     * 判断用户是否有效（未禁用且未锁定）
     */
    public boolean isValid() {
        return status != null && status == 1 && (isLocked == null || !isLocked);
    }
    
    /**
     * 判断用户是否被锁定
     */
    public boolean isLocked() {
        return isLocked != null && isLocked;
    }
    
    /**
     * 判断用户是否启用
     */
    public boolean isEnabled() {
        return status != null && status == 1;
    }
    
    /**
     * 判断密码是否过期
     */
    public boolean isPasswordExpired() {
        if (passwordExpireAt == null) {
            return false;
        }
        return LocalDateTime.now().isAfter(passwordExpireAt);
    }
    
    /**
     * 判断是否需要修改密码
     */
    public boolean needChangePassword() {
        // 密码过期或者从未修改过密码
        return isPasswordExpired() || lastPasswordChangeAt == null;
    }
    
    /**
     * 判断是否达到密码错误次数上限
     */
    public boolean isPasswordErrorLimitReached(int maxAttempts) {
        return passwordErrorCount != null && passwordErrorCount >= maxAttempts;
    }
    
    /**
     * 判断是否处于锁定期间
     */
    public boolean isInLockPeriod() {
        if (lockTime == null) {
            return false;
        }
        
        LocalDateTime now = LocalDateTime.now();
        
        // 如果设置了解锁时间，检查是否已过解锁时间
        if (unlockTime != null) {
            return now.isBefore(unlockTime);
        }
        
        // 如果没有设置解锁时间，则认为是永久锁定
        return true;
    }
    
    // ==================== Getter/Setter ====================
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }

    public String getTenantId() {
        return tenantId;
    }

    public void setTenantId(String tenantId) {
        this.tenantId = tenantId;
    }
    
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    public String getNickname() {
        return nickname;
    }
    
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    
    public String getDeptId() {
        return deptId;
    }
    
    public void setDeptId(String deptId) {
        this.deptId = deptId;
    }
    
    public String getPhone() {
        return phone;
    }
    
    public void setPhone(String phone) {
        this.phone = phone;
    }
    
    public String getEmail() {
        return email;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }
    
    public Boolean getEmailVerified() {
        return emailVerified;
    }
    
    public void setEmailVerified(Boolean emailVerified) {
        this.emailVerified = emailVerified;
    }
    
    
    public LocalDateTime getEmailVerifiedAt() {
        return emailVerifiedAt;
    }
    
    public void setEmailVerifiedAt(LocalDateTime emailVerifiedAt) {
        this.emailVerifiedAt = emailVerifiedAt;
    }
    
    public String getAvatarUrl() {
        return avatarUrl;
    }
    
    public void setAvatarUrl(String avatarUrl) {
        this.avatarUrl = avatarUrl;
    }
    
    public Integer getStatus() {
        return status;
    }
    
    public void setStatus(Integer status) {
        this.status = status;
    }
    
    public Boolean getIsLocked() {
        return isLocked;
    }
    
    public void setIsLocked(Boolean isLocked) {
        this.isLocked = isLocked;
    }
    
    public LocalDateTime getPasswordExpireAt() {
        return passwordExpireAt;
    }
    
    public void setPasswordExpireAt(LocalDateTime passwordExpireAt) {
        this.passwordExpireAt = passwordExpireAt;
    }
    
    public LocalDateTime getLastLoginTime() {
        return lastLoginTime;
    }
    
    public void setLastLoginTime(LocalDateTime lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }
    
    public LocalDateTime getLastPasswordChangeAt() {
        return lastPasswordChangeAt;
    }
    
    public void setLastPasswordChangeAt(LocalDateTime lastPasswordChangeAt) {
        this.lastPasswordChangeAt = lastPasswordChangeAt;
    }
    
    public Integer getPasswordErrorCount() {
        return passwordErrorCount;
    }
    
    public void setPasswordErrorCount(Integer passwordErrorCount) {
        this.passwordErrorCount = passwordErrorCount;
    }
    
    public LocalDateTime getLockTime() {
        return lockTime;
    }
    
    public void setLockTime(LocalDateTime lockTime) {
        this.lockTime = lockTime;
    }
    
    public LocalDateTime getUnlockTime() {
        return unlockTime;
    }
    
    public void setUnlockTime(LocalDateTime unlockTime) {
        this.unlockTime = unlockTime;
    }
    
    public Long getPermVersion() {
        return permVersion;
    }
    
    public void setPermVersion(Long permVersion) {
        this.permVersion = permVersion;
    }

    
    public String getLastLoginIp() {
        return lastLoginIp;
    }
    
    public void setLastLoginIp(String lastLoginIp) {
        this.lastLoginIp = lastLoginIp;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public java.util.List<Role> getRoles() {
        return roles;
    }
    
    public void setRoles(java.util.List<Role> roles) {
        this.roles = roles;
    }
    
    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", tenantId='" + tenantId + '\'' +
                ", username='" + username + '\'' +
                ", password='[PROTECTED]'" +
                ", nickname='" + nickname + '\'' +
                ", deptId='" + deptId + '\'' +
                ", phone='" + phone + '\'' +
                ", email='" + email + '\'' +
                ", avatarUrl='" + avatarUrl + '\'' +
                ", status=" + status +
                ", isLocked=" + isLocked +
                ", passwordExpireAt=" + passwordExpireAt +
                ", lastLoginTime=" + lastLoginTime +
                ", lastPasswordChangeAt=" + lastPasswordChangeAt +
                ", passwordErrorCount=" + passwordErrorCount +
                ", lockTime=" + lockTime +
                ", unlockTime=" + unlockTime +
                ", permVersion=" + permVersion +
                '}';
    }
}
